package pers.brozen.anka.support.wechat;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import pers.brozen.anka.support.wechat.request.OfficialAccountTemplateMessageSendParam;
import pers.brozen.anka.support.wechat.response.OfficialAccountGetAccessTokenResponse;
import pers.brozen.anka.support.wechat.response.OfficialAccountGetJsapiTicketResponse;
import pers.brozen.anka.support.wechat.response.OfficialAccountUserInfoResult;
import pers.brozen.anka.utils.HttpClientHolder;
import pers.brozen.anka.utils.json.JacksonUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 微信公众号相关接口
 *
 * @author Brozen
 * @date 2019/8/15 1:39 PM
 */
@Slf4j
public class WeChatOfficialAccountAPI extends WeChatAPI {

    public WeChatOfficialAccountAPI(String appId, String appSecret) {
        super(appId, appSecret);
    }

    /**
     * 公众号 使用登录code换取会话信息
     */
    public OfficialAccountGetAccessTokenResponse getSession(String code) {
        HttpClient client = HttpClientHolder.getClient();

        String url = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?grant_type=authorization_code&appid=%s&secret=%s&code=%s",
                getAppId(), getAppSecret(), code);

        try {
            HttpGet get = new HttpGet(url);
            HttpEntity entity = client.execute(get).getEntity();
            String response = EntityUtils.toString(entity, StandardCharsets.UTF_8);

            checkAndThrowErrorResponse(response);
            return JacksonUtils.parseObject(response, OfficialAccountGetAccessTokenResponse.class);
        } catch (IOException e) {
            log.error("获取会话异常", e);
            throw new WeChatException("500", "网络访问异常！");
        }
    }

    /**
     * 公众号 获取调用JSAPI的票据
     */
    public OfficialAccountGetJsapiTicketResponse getJsapiTicket() {
        throw new UnsupportedOperationException("暂未实现！ getJsapiTicket");
    }

    public OfficialAccountUserInfoResult getUserInfo(String openId) {
        HttpClient client = HttpClientHolder.getClient();
        String url = String.format("https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN",
                getAccessToken(), openId);

        try {
            HttpGet get = new HttpGet(url);
            HttpEntity entity = client.execute(get).getEntity();
            String response = EntityUtils.toString(entity, StandardCharsets.UTF_8);

            checkErrorResponse(response);
            return JacksonUtils.parseObject(response, OfficialAccountUserInfoResult.class);
        } catch (IOException e) {
            log.error("获取UserInfo异常", e);
            throw new WeChatException("500", "网络访问异常！");
        }
    }

    /**
     * 发送模板消息 返回msgid
     */
    public Integer sendMessage(OfficialAccountTemplateMessageSendParam param) {
        HttpClient client = HttpClientHolder.getClient();
        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + getAccessToken();

        try {
            HttpPost post = new HttpPost(url);
            post.setHeader("Content-Type", "application/json;charset=UTF-8");
            post.setEntity(new StringEntity(JacksonUtils.toJSONString(param), StandardCharsets.UTF_8));

            HttpEntity entity = client.execute(post).getEntity();
            String response = EntityUtils.toString(entity, StandardCharsets.UTF_8);

            Map jo = JacksonUtils.parseObject(response, Map.class);
            Integer errorCode = (Integer) jo.get("errcode");
            if (errorCode.equals(0)) {
                return (Integer) jo.get("msgid");
            } else {
                throw new WeChatException(jo.get("errcode").toString(), jo.get("errmsg").toString());
            }

        } catch (IOException e) {
            log.error("推送模板消息异常", e);
            throw new WeChatException("500", "网络访问异常！");
        }
    }

}
